package com.yzy.fly.config;

import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.dynamic.datasource.aop.DynamicDataSourceAnnotationInterceptor;
import com.baomidou.dynamic.datasource.processor.DsProcessor;
import com.baomidou.dynamic.datasource.support.DataSourceClassResolver;
import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
import com.yzy.fly.config.properties.DynamicDataSourceConfig;
import com.yzy.fly.config.properties.FlyProperties;
import lombok.extern.slf4j.Slf4j;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.commons.collections.MapUtils;

import java.util.Map;

@Slf4j
public class FlyDynamicDataSourceAnnotationInterceptor extends DynamicDataSourceAnnotationInterceptor {
    private final DataSourceClassResolver dataSourceClassResolver;
    private final DsProcessor dsProcessor;
    private final FlyProperties flyProperties;
    private final Map<String, String> mappings;

    public FlyDynamicDataSourceAnnotationInterceptor(Boolean allowedPublicOnly, DsProcessor dsProcessor, FlyProperties flyProperties) {
        super(allowedPublicOnly, dsProcessor);
        this.dataSourceClassResolver = new DataSourceClassResolver(allowedPublicOnly);
        this.dsProcessor = dsProcessor;
        this.flyProperties = flyProperties;

        DynamicDataSourceConfig dynamicDataSource = flyProperties.getConfiguration().getDynamicDataSource();
        Map<String, String> mappings = dynamicDataSource.getMappings();
        this.mappings = mappings;
    }

    public Object invoke(MethodInvocation invocation) throws Throwable {
        String dsKey = this.determineDatasourceKey(invocation);

//        invocation.getMethod().getAnnotations();
//        Object[] arguments = invocation.getArguments();
        //定义bean Name , 取值策略，

        String mappingDsKey = dsKey;
        if (MapUtils.isNotEmpty(mappings)) {
            mappingDsKey = mappings.getOrDefault(dsKey, dsKey);
        }

        if (log.isDebugEnabled()) {
            log.debug("dsKey:{} mappingDsKey:{}", dsKey, mappingDsKey);
        }

        DynamicDataSourceContextHolder.push(mappingDsKey);

        Object var3;
        try {
            var3 = invocation.proceed();
        } finally {
            DynamicDataSourceContextHolder.poll();
        }

        return var3;
    }

    private String determineDatasourceKey(MethodInvocation invocation) {
        String key = this.dataSourceClassResolver.findKey(invocation.getMethod(), invocation.getThis(), DS.class);
        return key.startsWith("#") ? this.dsProcessor.determineDatasource(invocation, key) : key;
    }
}
